﻿using Core.WebScaner;
using HtmlAgilityPack;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace WebScanner
{
    public class HtmlPageParser
    {
        internal void AddNewUris(Uri uri, List<WebRequestProperties> uriList)
        {
            Parallel.ForEach(uriList.Where(x => x.FileType == FileType.Page && x.StatusCode == HttpStatusCode.OK).ToList(), uriItem => FindUrisAndAddNew(uri, uriItem, uriList));
        }

        private void FindUrisAndAddNew(Uri uri, WebRequestProperties uriItem, List<WebRequestProperties> uriList)
        {
            uriItem.Content = String.Empty;
            lock (uriList)
            {
                AddNewUri(uri, uriList, uriItem.Uri, uriItem.LinksOnPage);
            }

        }

        private void AddNewUri(Uri uri, List<WebRequestProperties> uriList, Uri referalUri, IEnumerable<string> allUrls)
        {
            string uriLeftPart = uri.GetLeftPart(UriPartial.Authority);

            foreach (var url in allUrls)
            {
                if (String.IsNullOrWhiteSpace(url) || url.Equals("#"))
                    continue;

                string urlsWithAbsVirtPath = string.Empty;

                if (url[0] == '/')
                {
                    urlsWithAbsVirtPath = uriLeftPart + url;
                }
                else
                {
                    if (Uri.IsWellFormedUriString(url, UriKind.Absolute))
                    {
                        var newUri = new Uri(url);
                        if (!(newUri.GetLeftPart(UriPartial.Authority).Equals(uriLeftPart)))
                            continue;
                        else
                            urlsWithAbsVirtPath = url;
                    }
                    else
                    {
                        var uriExt = uri + url;
                        if (Uri.IsWellFormedUriString(uriExt, UriKind.Absolute))
                        {
                            urlsWithAbsVirtPath = uriExt;
                        }
                    }
                }

                if (!Uri.IsWellFormedUriString(urlsWithAbsVirtPath, UriKind.Absolute))
                    continue;

                var uriToAdd = new Uri(urlsWithAbsVirtPath);

                if (uriList.SingleOrDefault(x => x.Uri.Equals(uriToAdd)) == null)
                {

                    uriList.Add(new WebRequestProperties() { Uri = uriToAdd, ReferalUri = referalUri });
                }
            }

        }

        public IEnumerable<string> GetAllUrls(string html)
        {
            HtmlDocument htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(html);
            var aElements = htmlDoc.DocumentNode.SelectNodes("//a[@href]");
            if (aElements != null)
            {
                return aElements.Select(x => x.Attributes.SingleOrDefault(y => y.Name == "href") != null ? x.Attributes.SingleOrDefault(y => y.Name == "href").Value : null);
            }
            else
            {
                return new List<string>();
            }
        }



    }
}
